package com.njlime.core.helper.quartz;

import com.njlime.core.helper.SpringContextHolder;
import com.njlime.sys.entities.RegularTask;
import com.njlime.sys.service.RegularTaskService;
import org.apache.log4j.Logger;
import org.quartz.Job;
import org.quartz.JobDataMap;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

/**
 * 对定时任务添加了全局事务，继承此类的任务应当无需再进行事务控制
 * Created by Dean on 2017-9-8.
 */
public abstract class ExecuteJob implements Job {
    private static Logger logger = Logger.getLogger(ExecuteJob.class);
    protected RegularTaskService regularTaskService = SpringContextHolder.getBean("regularTaskService");
    private JpaTransactionManager transactionManager = SpringContextHolder.getBean("transactionManager");

    @Override
    public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        JobDataMap dataMap = jobExecutionContext.getJobDetail().getJobDataMap();
        String jobName = jobExecutionContext.getJobDetail().getKey().getName();
        //事务开始
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        def.setTimeout(30);
        //事务状态
        TransactionStatus status = transactionManager.getTransaction(def);
        try{
            run(dataMap);
            regularTaskService.updateRegularTaskStatus(jobName, RegularTask.RegularTaskStatus.EXECUTED);
            //事务提交
            transactionManager.commit(status);
        }catch (Exception e){
            logger.error(e.getMessage(),e);
            //事务回滚
            if(!status.isCompleted()){
                transactionManager.rollback(status);
            }
            regularTaskService.updateRegularTaskStatus(jobName, RegularTask.RegularTaskStatus.FAILED);
        }
    }

    public abstract void run(JobDataMap dataMap);
}
